package com.photoeditor.demo.model.image.collage.templet;

import android.graphics.Path;

import com.common.base.ComponentContext;
import com.common.base.utils.DeviceUtils;
import com.photoeditor.demo.model.image.collage.util.MathUtil;


/**
 * 用于计算圆角
 */
public class RoundPathUtil {

    public final static int MAX_ROUND_SIZE = DeviceUtils.dip2px(ComponentContext.getContext(), 75);

    public final static int MAX_DISTANCE_SIZE = DeviceUtils.dip2px(ComponentContext.getContext(), 20);


    public static Point getCenterPoint(Point one, Point two){
        return new Point((one.x + two.x) / 2, (one.y + two.y) / 2);
    }

    /**
     * 这个函数用于为Path计算
     * 注意x2, y2是真正的点， 而x1, y1和x3, y3是中心点 如下所示
     * C
     * |
     * |
     * (x3, y3)为AC的中点
     * |
     * |
     * |
     * A(x2, y2)———————(x1, y1)为AB的中点———————B
     * 方向是先(Path当前所在)x1, y1 -> x2, y2 -> x3, y3
     * @param path
     * @param x1
     * @param y1
     * @param x2
     * @param y2
     * @param x3
     * @param y3
     * @param progress
     */
    public static void countPath(Path path, float x1, float y1, float x2, float y2, float x3, float y3, int progress){
        float newX1 = x1 - x2;
        float newY1 = y1 - y2;
        float newX2 = 0;
        float newY2 = 0;
        float newX3 = x3 - x2;
        float newY3 = y3 - y2;

        float roundSize = MAX_ROUND_SIZE * progress * 1.0f / 100;

        float distance1 = (float)Math.sqrt(newX1 * newX1 + newY1 * newY1);
        float distance2 = (float)Math.sqrt(newX3 * newX3 + newY3 * newY3);

        int location1 = MathUtil.getLocation(newX1, newY1);
        int location2 = MathUtil.getLocation(newX3, newY3);

        //加这句话的原因是android的坐标系和  数学的坐标系 Y正轴方向是相反的，所以要取负值
        Line line1 = new Line(newX1, -newY1, newX2, -newY2);
        Line line2 = new Line(newX3, -newY3, newX2, -newY2);

        Point point1 = countBasePoint(line1, location1, Math.min(distance1, roundSize));
        point1.x = point1.x + x2;
        point1.y = -point1.y + y2;
        Point point2 = countBasePoint(line2, location2, Math.min(distance2, roundSize));
        point2.x = point2.x + x2;
        point2.y = -point2.y + y2;

        path.lineTo(point1.x, point1.y);
        path.cubicTo(point1.x, point1.y, x2, y2, point2.x, point2.y);
        path.lineTo(x3, y3);
    }

    /**
     * 计算圆角的起始点
     * @param line
     * @param location
     * @param distance
     * @return
     */
    private static Point countBasePoint(Line line, int location, float distance){
        Point point = new Point(0, 0);
        if(line.isHrizontal()){
            point.x = distance;
            point.y = 0;
        } else if(line.isVertical()){
            point.x = 0;
            point.y = distance;
        } else {
            double degree = Math.abs(Math.toDegrees(Math.atan(line.getK())));
            float radians = (float) Math.toRadians(degree);
            point.x = (float) (distance * Math.cos(radians));
            point.y = (float) (distance * Math.sin(radians));
        }
        if (location == 2) {
            point.x = -point.x;
        } else if (location == 3) {
            point.x = -point.x;
            point.y = -point.y;
        } else if (location == 4) {
            point.y = -point.y;
        }
        return point;
    }


    /**
     *
     * @param path  需要写入的Path  不能为空
     * @param points  是所有的点
     * @param trueWidth  当前View的宽
     * @param trueHeight  当前View的高
     * @param progress  圆角的进度 0 - 100
     * @return
     */
    public static void getFitPath(Path path, CollagePoints points, float trueWidth, float trueHeight, int progress, int distanceProgress){
        path.reset();
        if(progress == 0){
            int number = points.getLength();
            Point first = points.getCurrentPoint(0, trueWidth, trueHeight, distanceProgress);
            path.moveTo(first.x, first.y);
            for(int i = 1 ; i < number ; i++){
                Point point = points.getCurrentPoint(i, trueWidth, trueHeight, distanceProgress);
                path.lineTo(point.x, point.y);
            }
            path.close();
        } else{
            int number = points.getLength();
            Point first = points.getCurrentPoint(0, trueWidth, trueHeight, distanceProgress);
            Point second = points.getCurrentPoint(1, trueWidth, trueHeight, distanceProgress);
            Point centerPoint1 = getCenterPoint(first, second);

            path.moveTo(centerPoint1.x, centerPoint1.y);
            Point centerPoint2 = null;
            for(int i = 1 ; i < number - 1 ; i++){
                Point point = points.getCurrentPoint(i, trueWidth, trueHeight, distanceProgress);
                Point nextPoint = points.getCurrentPoint(i + 1, trueWidth, trueHeight, distanceProgress);
                centerPoint2 = getCenterPoint(point, nextPoint);
                countPath(path, centerPoint1.x, centerPoint1.y
                        , point.x, point.y
                        , centerPoint2.x, centerPoint2.y
                        , progress);
                centerPoint1.set(centerPoint2);
            }
            //最后一个
            Point last = points.getCurrentPoint(number - 1, trueWidth, trueHeight, distanceProgress);
            centerPoint2 = getCenterPoint(first, last);
            countPath(path, centerPoint1.x, centerPoint1.y
                    , last.x, last.y
                    , centerPoint2.x, centerPoint2.y
                    , progress);
            centerPoint1.set(centerPoint2);

            //第一个点
            centerPoint2 = getCenterPoint(first, second);
            countPath(path, centerPoint1.x, centerPoint1.y
                    , first.x, first.y
                    , centerPoint2.x, centerPoint2.y
                    , progress);
        }
    }

    /**
     *
     * @param points  是所有的点
     * @param trueWidth  当前View的宽
     * @param trueHeight  当前View的高
     * @param progress  圆角的进度 0 - 100
     * @return
     */
    public static Path getFitPath(CollagePoints points, float trueWidth, float trueHeight, int progress, int distanceProgress){
        Path path = new Path();
        if(progress == 0){
            int number = points.getLength();
            Point first = points.getCurrentPoint(0, trueWidth, trueHeight, distanceProgress);
            path.moveTo(first.x, first.y);
            for(int i = 1 ; i < number ; i++){
                Point point = points.getCurrentPoint(i, trueWidth, trueHeight, distanceProgress);
                path.lineTo(point.x, point.y);
            }
            path.close();
        } else{
            int number = points.getLength();
            Point first = points.getCurrentPoint(0, trueWidth, trueHeight, distanceProgress);
            Point second = points.getCurrentPoint(1, trueWidth, trueHeight, distanceProgress);
            Point centerPoint1 = getCenterPoint(first, second);

            path.moveTo(centerPoint1.x, centerPoint1.y);
            Point centerPoint2 = null;
            for(int i = 1 ; i < number - 1 ; i++){
                Point point = points.getCurrentPoint(i, trueWidth, trueHeight, distanceProgress);
                Point nextPoint = points.getCurrentPoint(i + 1, trueWidth, trueHeight, distanceProgress);
                centerPoint2 = getCenterPoint(point, nextPoint);
                countPath(path, centerPoint1.x, centerPoint1.y
                        , point.x, point.y
                        , centerPoint2.x, centerPoint2.y
                        , progress);
                centerPoint1.set(centerPoint2);
            }
            //最后一个
            Point last = points.getCurrentPoint(number - 1, trueWidth, trueHeight, distanceProgress);
            centerPoint2 = getCenterPoint(first, last);
            countPath(path, centerPoint1.x, centerPoint1.y
                    , last.x, last.y
                    , centerPoint2.x, centerPoint2.y
                    , progress);
            centerPoint1.set(centerPoint2);

            //第一个点
            centerPoint2 = getCenterPoint(first, second);
            countPath(path, centerPoint1.x, centerPoint1.y
                    , first.x, first.y
                    , centerPoint2.x, centerPoint2.y
                    , progress);
        }

        return path;
    }
}
